package com.mingke.java.GroupChatPro;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;

/**
 * @author mingke
 * @function 群聊系统Pro读入客户端消息的回调
 * @date 2021/11/10
 */
public class GroupReadHandler implements CompletionHandler<Integer, ByteBuffer> {

    private AsynchronousSocketChannel socketChannel;

    public AsynchronousSocketChannel getSocketChannel() {
        return socketChannel;
    }

    public void setSocketChannel(AsynchronousSocketChannel socketChannel) {
        this.socketChannel = socketChannel;
    }

    //自定义的构造函数
    public GroupReadHandler(AsynchronousSocketChannel socketChannel) {
        this.socketChannel = socketChannel;
    }

    @Override
    public void completed(Integer len, ByteBuffer byteBuffer) {
        String userName = GroupAcceptHandler.userNames[socketChannel.hashCode() % 10];
        String msg = null;
        if(len == -1) {
            //如果客户端已经下线，广播下线消息并释放相应的通道
            msg = "系统消息@ 客户端："+userName+"已经下线";
            //将客户端移除
            GroupAcceptHandler.socketChannels.remove(socketChannel.hashCode());
            try {
                socketChannel.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else {
            //切换成读入模式
            byteBuffer.flip();
            int bufferLength = byteBuffer.limit();
            byte bytes[] = new byte[bufferLength];
            byteBuffer.get(bytes, 0, bufferLength);
            msg = userName + ": " + new String(bytes, Charset.forName("UTF-8"));
            //清理缓冲区
            byteBuffer.clear();
            //使得客户端通道能够继续处理客户端发送过来的消息
            socketChannel.read(byteBuffer, byteBuffer, this);
        }
        //向其他用户广播当前客户端发的消息
        GroupAcceptHandler.boardcast(msg, socketChannel);
    }

    @Override
    public void failed(Throwable exc, ByteBuffer byteBuffer) {
        try {
            exc.printStackTrace();
        }finally {
            System.out.println("读取数据遇到了一点问题");
            socketChannel.read(byteBuffer, byteBuffer, this);
        }
    }
}
